﻿using gt.rediscachemanager.Entry;
using StackExchange.Redis;
using System;
using System.Threading.Tasks;

namespace gt.rediscachemanager.Core.Executor
{
    internal class StackExchangeRedisExecutor : IRedisExecutor
    {
        private IConnectionMultiplexer m_connection;
        private IDatabase m_database;

        public StackExchangeRedisExecutor(IConnectionMultiplexer conn, int db = -1)
        {
            this.m_connection = conn;
            this.m_database = conn.GetDatabase(db);
        }

        public EMRedisResult ExecuteCommand(Entry.RedisCommand command, EMRedisMessage message, CommandFlags commandFlags)
        {
            if (message == null) throw new ArgumentNullException("message");
            switch (command)
            {
                case RedisCommand.Info:
                    message.Result = EMRedisResult.Create(this.m_connection.GetServer(message.CommonValue).InfoRaw());
                    break;
                case RedisCommand.ClientList:
                    message.Result = EMRedisResult.Create(this.m_connection.GetServer(message.CommonValue).ClientList());
                    break;
                case RedisCommand.StringGet:
                    message.Result = EMRedisResult.Create(this.m_database.StringGet(message.Key, commandFlags));
                    break;
                case RedisCommand.StringGetSet:
                    message.Result = EMRedisResult.Create(this.m_database.StringGetSet(message.Key, message.StringValue.Value, commandFlags));
                    break;
                case RedisCommand.StringSet:
                    message.Result = EMRedisResult.Create(this.m_database.StringSet(message.Key, message.StringValue.Value, message.ExpiredTime,
                        message.When, commandFlags));
                    break;
                case RedisCommand.StringSetArray:
                    message.Result = EMRedisResult.Create(this.m_database.StringSet(message.StringValue.KeyValues, When.Always, commandFlags));
                    break;
                case RedisCommand.StringAppend:
                    message.Result = EMRedisResult.Create(this.m_database.StringAppend(message.Key, message.StringValue.Value, commandFlags));
                    break;
                case RedisCommand.StringIncrement:
                    message.Result = EMRedisResult.Create(this.m_database.StringIncrement(message.Key, message.StringValue.IncrOrDecrValue, commandFlags));
                    break;
                case RedisCommand.KeyExists:
                    message.Result = EMRedisResult.Create(this.m_database.KeyExists(message.Key, commandFlags));
                    break;
                case RedisCommand.KeyRemove:
                    message.Result = EMRedisResult.Create(this.m_database.KeyDelete(message.Key, commandFlags));
                    break;
                case RedisCommand.KeyRemoveArray:
                    message.Result = EMRedisResult.Create(this.m_database.KeyDelete(message.Keys, commandFlags));
                    break;
                case RedisCommand.KeyExpired:
                    message.Result = EMRedisResult.Create(this.m_database.KeyExpire(message.Key, message.ExpiredTime, commandFlags));
                    break;
                case RedisCommand.KeyTimeToLive:
                    message.Result = EMRedisResult.Create(this.m_database.KeyTimeToLive(message.Key, commandFlags));
                    break;
                case RedisCommand.HashGet:
                    message.Result = EMRedisResult.Create(this.m_database.HashGet(message.Key, message.HashValue.Field, commandFlags));
                    break;
                case RedisCommand.HashGetByArray:
                    message.Result = EMRedisResult.Create(this.m_database.HashGet(message.Key, message.HashValue.Fields, commandFlags));
                    break;
                case RedisCommand.HashGetAll:
                    message.Result = EMRedisResult.Create(this.m_database.HashGetAll(message.Key, commandFlags));
                    break;
                case RedisCommand.HashSet:
                    message.Result = EMRedisResult.Create(this.m_database.HashSet(message.Key, message.HashValue.Field, message.HashValue.Value, message.When, commandFlags));
                    break;
                case RedisCommand.HashSetArray:
                    this.m_database.HashSet(message.Key, message.HashValue.HashEntries, commandFlags);
                    message.Result = EMRedisResult.Create(true);
                    break;
                case RedisCommand.HashExist:
                    message.Result = EMRedisResult.Create(this.m_database.HashExists(message.Key, message.HashValue.Field, commandFlags));
                    break;
                case RedisCommand.HashRemove:
                    message.Result = EMRedisResult.Create(this.m_database.HashDelete(message.Key, message.HashValue.Field, commandFlags));
                    break;
                case RedisCommand.HashRemoveArray:
                    message.Result = EMRedisResult.Create(this.m_database.HashDelete(message.Key, message.HashValue.Fields, commandFlags));
                    break;
                case RedisCommand.HashIncrement:
                    message.Result = EMRedisResult.Create(this.m_database.HashIncrement(message.Key, message.HashValue.Field, message.HashValue.IncrOrDecrValue, commandFlags));
                    break;
                case RedisCommand.HashScan:
                    message.Result = EMRedisResult.Create(this.m_database.HashScan(message.Key, message.ScanValue.FieldPattern ?? RedisValue.Null,
                        message.ScanValue.PageSize, message.ScanValue.Cursor, message.ScanValue.PageOffset, commandFlags));
                    break;
                case RedisCommand.HashFields:
                    message.Result = EMRedisResult.Create(this.m_database.HashKeys(message.Key, commandFlags));
                    break;
                case RedisCommand.HashValues:
                    message.Result = EMRedisResult.Create(this.m_database.HashValues(message.Key, commandFlags));
                    break;
                case RedisCommand.HashLength:
                    message.Result = EMRedisResult.Create(this.m_database.HashLength(message.Key, commandFlags));
                    break;
                case RedisCommand.ListGetByIndex:
                    message.Result = EMRedisResult.Create(this.m_database.ListGetByIndex(message.Key, message.ListValue.Index, commandFlags));
                    break;
                case RedisCommand.ListInsertAfter:
                    message.Result = EMRedisResult.Create(this.m_database.ListInsertAfter(message.Key, message.ListValue.Pivot,
                        message.ListValue.Value, commandFlags));
                    break;
                case RedisCommand.ListInsertBefore:
                    message.Result = EMRedisResult.Create(this.m_database.ListInsertBefore(message.Key, message.ListValue.Pivot,
                        message.ListValue.Value, commandFlags));
                    break;
                case RedisCommand.ListLeftPop:
                    message.Result = EMRedisResult.Create(this.m_database.ListLeftPop(message.Key, commandFlags));
                    break;
                case RedisCommand.ListLeftPush:
                    message.Result = EMRedisResult.Create(this.m_database.ListLeftPush(message.Key, message.ListValue.Value, When.Always, commandFlags));
                    break;
                case RedisCommand.ListLength:
                    message.Result = EMRedisResult.Create(this.m_database.ListLength(message.Key, commandFlags));
                    break;
                case RedisCommand.ListRange:
                    message.Result = EMRedisResult.Create(this.m_database.ListRange(message.Key, message.ListValue.FirstIndex,
                        message.ListValue.SecondIndex, commandFlags));
                    break;
                case RedisCommand.ListRightPop:
                    message.Result = EMRedisResult.Create(this.m_database.ListRightPop(message.Key, commandFlags));
                    break;
                case RedisCommand.ListRightPush:
                    message.Result = EMRedisResult.Create(this.m_database.ListRightPush(message.Key, message.ListValue.Value, message.When, commandFlags));
                    break;
                case RedisCommand.ListSetByIndex:
                    this.m_database.ListSetByIndex(message.Key, message.ListValue.Index, message.ListValue.Value, commandFlags);
                    message.Result = EMRedisResult.Create(true);
                    break;
                case RedisCommand.ListTrim:
                    this.m_database.ListTrim(message.Key, message.ListValue.FirstIndex, message.ListValue.SecondIndex, commandFlags);
                    message.Result = EMRedisResult.Create(true);
                    break;
                case RedisCommand.ListRemove:
                    message.Result = EMRedisResult.Create(this.m_database.ListRemove(message.Key, message.ListValue.Value, message.ListValue.Count, commandFlags));
                    break;
                case RedisCommand.LockTake:
                    message.Result = EMRedisResult.Create(this.m_database.LockTake(message.Key, message.CommonValue, message.ExpiredTime.Value, commandFlags));
                    break;
                case RedisCommand.LockQuery:
                    message.Result = EMRedisResult.Create(this.m_database.LockQuery(message.Key, commandFlags));
                    break;
                case RedisCommand.LockRelease:
                    message.Result = EMRedisResult.Create(this.m_database.LockRelease(message.Key, message.CommonValue, commandFlags));
                    break;
                case RedisCommand.SetAdd:
                    message.Result = EMRedisResult.Create(this.m_database.SetAdd(message.Key, message.SetValue.Value, commandFlags));
                    break;
                case RedisCommand.SetAddArray:
                    message.Result = EMRedisResult.Create(this.m_database.SetAdd(message.Key, message.SetValue.Values, commandFlags));
                    break;
                case RedisCommand.SetCombine:
                    message.Result = EMRedisResult.Create(this.m_database.SetCombine(message.SetValue.Operation, message.SetValue.First, message.SetValue.Second, commandFlags));
                    break;
                case RedisCommand.SetCombineAndStore:
                    message.Result = EMRedisResult.Create(this.m_database.SetCombineAndStore(message.SetValue.Operation, message.SetValue.Destination,
                        message.SetValue.First, message.SetValue.Second, commandFlags));
                    break;
                case RedisCommand.SetCombineAndStoreArray:
                    message.Result = EMRedisResult.Create(this.m_database.SetCombineAndStore(message.SetValue.Operation, message.SetValue.Destination, message.SetValue.Keys, commandFlags));
                    break;
                case RedisCommand.SetCombineArray:
                    message.Result = EMRedisResult.Create(this.m_database.SetCombine(message.SetValue.Operation, message.SetValue.Keys, commandFlags));
                    break;
                case RedisCommand.SetContains:
                    message.Result = EMRedisResult.Create(this.m_database.SetContains(message.Key, message.SetValue.Value, commandFlags));
                    break;
                case RedisCommand.SetLength:
                    message.Result = EMRedisResult.Create(this.m_database.SetLength(message.Key, commandFlags));
                    break;
                case RedisCommand.SetMembers:
                    message.Result = EMRedisResult.Create(this.m_database.SetMembers(message.Key, commandFlags));
                    break;
                case RedisCommand.SetMove:
                    message.Result = EMRedisResult.Create(this.m_database.SetMove(message.SetValue.Source, message.SetValue.Destination, message.SetValue.Value, commandFlags));
                    break;
                case RedisCommand.SetPop:
                    message.Result = EMRedisResult.Create(this.m_database.SetPop(message.Key, commandFlags));
                    break;
                case RedisCommand.SetRandomMember:
                    message.Result = EMRedisResult.Create(this.m_database.SetRandomMember(message.Key, commandFlags));
                    break;
                case RedisCommand.SetRandomMembers:
                    message.Result = EMRedisResult.Create(this.m_database.SetRandomMembers(message.Key, message.SetValue.Count, commandFlags));
                    break;
                case RedisCommand.SetRemove:
                    message.Result = EMRedisResult.Create(this.m_database.SetRemove(message.Key, message.SetValue.Value, commandFlags));
                    break;
                case RedisCommand.SetRemoveArray:
                    message.Result = EMRedisResult.Create(this.m_database.SetRemove(message.Key, message.SetValue.Values, commandFlags));
                    break;
                case RedisCommand.SortedSetAdd:
                    message.Result = EMRedisResult.Create(this.m_database.SortedSetAdd(message.Key, message.SortedSetValue.Member, message.SortedSetValue.Score,
                        message.When, commandFlags));
                    break;
                case RedisCommand.SortedSetDecrement:
                    message.Result = EMRedisResult.Create(this.m_database.SortedSetDecrement(message.Key, message.SortedSetValue.Member,
                        message.SortedSetValue.IncreOrDecreValue, commandFlags));
                    break;
                case RedisCommand.SortedSetIncrement:
                    message.Result = EMRedisResult.Create(this.m_database.SortedSetIncrement(message.Key, message.SortedSetValue.Member,
                        message.SortedSetValue.IncreOrDecreValue, commandFlags));
                    break;
                case RedisCommand.SortedSetLength:
                    message.Result = EMRedisResult.Create(this.m_database.SortedSetLength(message.Key, message.SortedSetValue.Min, message.SortedSetValue.Max,
                        message.SortedSetValue.Exclude, commandFlags));
                    break;
                case RedisCommand.SortedSetRangeByRank:
                    message.Result = EMRedisResult.Create(this.m_database.SortedSetRangeByRank(message.Key, message.SortedSetValue.Start, message.SortedSetValue.Stop,
                        message.SortedSetValue.Order, commandFlags));
                    break;
                case RedisCommand.SortedSetRangeByScore:
                    message.Result = EMRedisResult.Create(this.m_database.SortedSetRangeByScore(message.Key, message.SortedSetValue.ScoreStart, message.SortedSetValue.ScoreStop,
                        message.SortedSetValue.Exclude, message.SortedSetValue.Order, message.SortedSetValue.Skip, message.SortedSetValue.Take, commandFlags));
                    break;
                case RedisCommand.SortedSetRemove:
                    message.Result = EMRedisResult.Create(this.m_database.SortedSetRemove(message.Key, message.SortedSetValue.Member, commandFlags));
                    break;
                case RedisCommand.HyperLogLogAdd:
                    message.Result = EMRedisResult.Create(this.m_database.HyperLogLogAdd(message.Key, message.HyperLogLogValue.Value, commandFlags));
                    break;
                case RedisCommand.HyperLogLogAddArray:
                    message.Result = EMRedisResult.Create(this.m_database.HyperLogLogAdd(message.Key, message.HyperLogLogValue.Values, commandFlags));
                    break;
                case RedisCommand.HyperLogLogLength:
                    message.Result = EMRedisResult.Create(this.m_database.HyperLogLogLength(message.Key, commandFlags));
                    break;
                case RedisCommand.HyperLogLogLengthArray:
                    message.Result = EMRedisResult.Create(this.m_database.HyperLogLogLength(message.HyperLogLogValue.Keys, commandFlags));
                    break;
                case RedisCommand.HyperLogLogMerge:
                    this.m_database.HyperLogLogMerge(message.HyperLogLogValue.Destination, message.HyperLogLogValue.First, message.HyperLogLogValue.Second, commandFlags);
                    message.Result = EMRedisResult.Create(true);
                    break;
                case RedisCommand.HyperLogLogMergeArray:
                    this.m_database.HyperLogLogMerge(message.HyperLogLogValue.Destination, message.HyperLogLogValue.Keys, commandFlags);
                    message.Result = EMRedisResult.Create(true);
                    break;
                case RedisCommand.StringBitCount:
                    message.Result = EMRedisResult.Create(this.m_database.StringBitCount(message.Key, message.BitValue.Start, message.BitValue.End, commandFlags));
                    break;
                case RedisCommand.StringBitOperation:
                    message.Result = EMRedisResult.Create(this.m_database.StringBitOperation(message.BitValue.Operation, message.BitValue.Destination, message.BitValue.First,
                        message.BitValue.Second, commandFlags));
                    break;
                case RedisCommand.StringBitOperationArray:
                    message.Result = EMRedisResult.Create(this.m_database.StringBitOperation(message.BitValue.Operation, message.BitValue.Destination, message.BitValue.Keys, commandFlags));
                    break;
                case RedisCommand.StringBitPosition:
                    message.Result = EMRedisResult.Create(this.m_database.StringBitPosition(message.Key, message.BitValue.Bit, message.BitValue.Start, message.BitValue.End, commandFlags));
                    break;
                case RedisCommand.StringGetBit:
                    message.Result = EMRedisResult.Create(this.m_database.StringGetBit(message.Key, message.BitValue.Offset, commandFlags));
                    break;
                case RedisCommand.StringSetBit:
                    message.Result = EMRedisResult.Create(this.m_database.StringSetBit(message.Key, message.BitValue.Offset, message.BitValue.Bit, commandFlags));
                    break;
                default:
                    throw new InvalidOperationException("execute command do not support this:" + command.ToString());
            }
            return message.Result;
        }

        public async Task<EMRedisResult> ExecuteCommandAsync(Entry.RedisCommand command, EMRedisMessage message, CommandFlags commandFlags)
        {
            if (message == null) throw new InvalidOperationException("command get a error message type！");
            switch (command)
            {
                case RedisCommand.StringGet:
                    message.Result = await this.m_database.StringGetAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringGetSet:
                    message.Result = await this.m_database.StringGetSetAsync(message.Key, message.StringValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringSet:
                    message.Result = await this.m_database.StringSetAsync(message.Key, message.StringValue.Value, message.ExpiredTime,
                        message.When, commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringSetArray:
                    message.Result = await this.m_database.StringSetAsync(message.StringValue.KeyValues, message.When, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringAppend:
                    message.Result = await this.m_database.StringAppendAsync(message.Key, message.StringValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringIncrement:
                    message.Result = await this.m_database.StringIncrementAsync(message.Key, message.StringValue.IncrOrDecrValue, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyExists:
                    message.Result = await this.m_database.KeyExistsAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyRemove:
                    message.Result = await this.m_database.KeyDeleteAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyRemoveArray:
                    message.Result = await this.m_database.KeyDeleteAsync(message.Keys, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyExpired:
                    message.Result = await this.m_database.KeyExpireAsync(message.Key, message.ExpiredTime, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.KeyTimeToLive:
                    message.Result = await this.m_database.KeyTimeToLiveAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashGet:
                    message.Result = await this.m_database.HashGetAsync(message.Key, message.HashValue.Field, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashGetByArray:
                    message.Result = await this.m_database.HashGetAsync(message.Key, message.HashValue.Fields, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashGetAll:
                    message.Result = await this.m_database.HashGetAllAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashSet:
                    message.Result = await this.m_database.HashSetAsync(message.Key, message.HashValue.Field, message.HashValue.Value, message.When, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashSetArray:
                    await this.m_database.HashSetAsync(message.Key, message.HashValue.HashEntries, commandFlags).ConfigureAwait(false);
                    message.Result = EMRedisResult.Create(true);
                    break;
                case RedisCommand.HashExist:
                    message.Result = await this.m_database.HashExistsAsync(message.Key, message.HashValue.Field, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashRemove:
                    message.Result = await this.m_database.HashDeleteAsync(message.Key, message.HashValue.Field, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashRemoveArray:
                    message.Result = await this.m_database.HashDeleteAsync(message.Key, message.HashValue.Fields, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashIncrement:
                    message.Result = await this.m_database.HashIncrementAsync(message.Key, message.HashValue.Field, message.HashValue.IncrOrDecrValue, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashFields:
                    message.Result = await this.m_database.HashKeysAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashValues:
                    message.Result = await this.m_database.HashValuesAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HashLength:
                    message.Result = await this.m_database.HashLengthAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListGetByIndex:
                    message.Result = await this.m_database.ListGetByIndexAsync(message.Key, message.ListValue.Index, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListInsertAfter:
                    message.Result = await this.m_database.ListInsertAfterAsync(message.Key, message.ListValue.Pivot, message.ListValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListInsertBefore:
                    message.Result = await this.m_database.ListInsertBeforeAsync(message.Key, message.ListValue.Pivot, message.ListValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListLeftPop:
                    message.Result = await this.m_database.ListLeftPopAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListLeftPush:
                    message.Result = await this.m_database.ListLeftPushAsync(message.Key, message.ListValue.Value, message.When, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListLength:
                    message.Result = await this.m_database.ListLengthAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListRange:
                    message.Result = await this.m_database.ListRangeAsync(message.Key, message.ListValue.FirstIndex, message.ListValue.SecondIndex, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListRightPop:
                    message.Result = await this.m_database.ListRightPopAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListRightPush:
                    message.Result = await this.m_database.ListRightPushAsync(message.Key, message.ListValue.Value, message.When, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListSetByIndex:
                    await this.m_database.ListSetByIndexAsync(message.Key, message.ListValue.Index, message.ListValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(true);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListTrim:
                    await this.m_database.ListTrimAsync(message.Key, message.ListValue.FirstIndex, message.ListValue.SecondIndex, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(true);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.ListRemove:
                    message.Result = await this.m_database.ListRemoveAsync(message.Key, message.ListValue.Value, message.ListValue.Count, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetAdd:
                    message.Result = await this.m_database.SetAddAsync(message.Key, message.SetValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetAddArray:
                    message.Result = await this.m_database.SetAddAsync(message.Key, message.SetValue.Values, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetCombine:
                    message.Result = await this.m_database.SetCombineAsync(message.SetValue.Operation, message.SetValue.First, message.SetValue.Second, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetCombineAndStore:
                    message.Result = await this.m_database.SetCombineAndStoreAsync(message.SetValue.Operation, message.SetValue.Destination, message.SetValue.First,
                        message.SetValue.Second, commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetCombineAndStoreArray:
                    message.Result = await this.m_database.SetCombineAndStoreAsync(message.SetValue.Operation, message.SetValue.Destination, message.SetValue.Keys, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetCombineArray:
                    message.Result = await this.m_database.SetCombineAsync(message.SetValue.Operation, message.SetValue.Keys, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetContains:
                    message.Result = await this.m_database.SetContainsAsync(message.Key, message.SetValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetLength:
                    message.Result = await this.m_database.SetLengthAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetMembers:
                    message.Result = await this.m_database.SetMembersAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetMove:
                    message.Result = await this.m_database.SetMoveAsync(message.SetValue.Source, message.SetValue.Destination, message.SetValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetPop:
                    message.Result = await this.m_database.SetPopAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetRandomMember:
                    message.Result = await this.m_database.SetRandomMemberAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetRandomMembers:
                    message.Result = await this.m_database.SetRandomMembersAsync(message.Key, message.SetValue.Count, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetRemove:
                    message.Result = await this.m_database.SetRemoveAsync(message.Key, message.SetValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SetRemoveArray:
                    message.Result = await this.m_database.SetRemoveAsync(message.Key, message.SetValue.Values, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetAdd:
                    message.Result = await this.m_database.SortedSetAddAsync(message.Key, message.SortedSetValue.Member, message.SortedSetValue.Score,
                        message.When, commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetDecrement:
                    message.Result = await this.m_database.SortedSetDecrementAsync(message.Key, message.SortedSetValue.Member, message.SortedSetValue.IncreOrDecreValue,
                        commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetIncrement:
                    message.Result = await this.m_database.SortedSetIncrementAsync(message.Key, message.SortedSetValue.Member, message.SortedSetValue.IncreOrDecreValue,
                        commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetLength:
                    message.Result = await this.m_database.SortedSetLengthAsync(message.Key, message.SortedSetValue.Min, message.SortedSetValue.Max,
                        message.SortedSetValue.Exclude, commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetRangeByRank:
                    message.Result = await this.m_database.SortedSetRangeByRankAsync(message.Key, message.SortedSetValue.Start, message.SortedSetValue.Stop,
                        message.SortedSetValue.Order, commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetRangeByScore:
                    message.Result = await this.m_database.SortedSetRangeByScoreAsync(message.Key, message.SortedSetValue.ScoreStart, message.SortedSetValue.ScoreStop,
                        message.SortedSetValue.Exclude, message.SortedSetValue.Order, message.SortedSetValue.Skip, message.SortedSetValue.Take, commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.SortedSetRemove:
                    message.Result = await this.m_database.SortedSetRemoveAsync(message.Key, message.SortedSetValue.Member, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogAdd:
                    message.Result = await this.m_database.HyperLogLogAddAsync(message.Key, message.HyperLogLogValue.Value, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogAddArray:
                    message.Result = await this.m_database.HyperLogLogAddAsync(message.Key, message.HyperLogLogValue.Values, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogLength:
                    message.Result = await this.m_database.HyperLogLogLengthAsync(message.Key, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogLengthArray:
                    message.Result = await this.m_database.HyperLogLogLengthAsync(message.HyperLogLogValue.Keys, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogMerge:
                    await this.m_database.HyperLogLogMergeAsync(message.HyperLogLogValue.Destination, message.HyperLogLogValue.First, message.HyperLogLogValue.Second,
                        commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(true);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.HyperLogLogMergeArray:
                    await this.m_database.HyperLogLogMergeAsync(message.HyperLogLogValue.Destination, message.HyperLogLogValue.Keys, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(true);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringBitCount:
                    message.Result = await this.m_database.StringBitCountAsync(message.Key, message.BitValue.Start, message.BitValue.End, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringBitOperation:
                    message.Result = await this.m_database.StringBitOperationAsync(message.BitValue.Operation, message.BitValue.Destination, message.BitValue.First,
                        message.BitValue.Second, commandFlags).ContinueWith(t =>
                        {
                            return EMRedisResult.Create(t.Result);
                        }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringBitOperationArray:
                    message.Result = await this.m_database.StringBitOperationAsync(message.BitValue.Operation, message.BitValue.Destination, message.BitValue.Keys, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringBitPosition:
                    message.Result = await this.m_database.StringBitPositionAsync(message.Key, message.BitValue.Bit, message.BitValue.Start, message.BitValue.End, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringGetBit:
                    message.Result = await this.m_database.StringGetBitAsync(message.Key, message.BitValue.Offset, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                case RedisCommand.StringSetBit:
                    message.Result = await this.m_database.StringSetBitAsync(message.Key, message.BitValue.Offset, message.BitValue.Bit, commandFlags).ContinueWith(t =>
                    {
                        return EMRedisResult.Create(t.Result);
                    }).ConfigureAwait(false);
                    break;
                default:
                    throw new InvalidOperationException("execute async command do not support this:" + command.ToString());
            }
            return message.Result;
        }
    }
}
